/**
 * 
 */
package ciprian.google.provider;

import android.content.ContentProvider;
import android.content.ContentUris;
import android.content.ContentValues;
import android.content.Context;
import android.content.UriMatcher;
import android.database.Cursor;
import android.database.SQLException;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteDatabase.CursorFactory;
import android.database.sqlite.SQLiteOpenHelper;
import android.database.sqlite.SQLiteQueryBuilder;
import android.net.Uri;

/**
 * @author Ciprian Ursu
 * 
 */
public class TransportContentProvider extends ContentProvider {
    public static final String AUTHORITY = "ciprian.google.provider.TransportContentProvider";
    public static final int TRANSPORT = 1;

    public static final String CONTENT_TYPE = "vnd.android.cursor.dir/vnd.transport.MapPoint";
    public static final Uri CONTENT_URI = Uri.parse("content://" + AUTHORITY);

    /**
     * SQLite DB Helper.
     */
    public static class MySQLiteDBHelper extends SQLiteOpenHelper {
        public static final String SQL_DB_NAME = "transport.db";
        public static final String SQL_MAIN_TABLE_NAME = "db_table";
        public static final String COLUMN_ID = "_ID";
        public static final String COLUMN_LAT = "latitude";
        public static final String COLUMN_LON = "longitude";
        public static final String COLUMN_ALT = "altitude";
        public static final String COLUMN_ROUTE_FILE_NAME = "route_file_name";
        public static final String COLUMN_TIME = "time";
        public static final String COLUMN_NAME = "name";
        public static final String COLUMN_TYPE = "type";

        private static final int DATABASE_VERSION = 6;

        public static final String SQL_CREATE_TABLE_STATEMENT = "CREATE TABLE "
                + SQL_MAIN_TABLE_NAME + "(" + COLUMN_ID + " INTEGER PRIMARY KEY AUTOINCREMENT, "
                + COLUMN_LAT + " double NOT NULL, " + COLUMN_LON + " double NOT NULL, "
                + COLUMN_ALT + " double NOT NULL, " + COLUMN_ROUTE_FILE_NAME + " String,"
                + COLUMN_TIME + " long NOT NULL, " + COLUMN_NAME + " String, " + COLUMN_TYPE
                + " int NOT NULL )";

        /**
         * Instantiates an open helper for the provider's SQLite data repository
         * Do not do database creation and upgrade here.
         */
        public MySQLiteDBHelper(Context context, String name, CursorFactory factory, int version) {
            super(context, name, factory, version);
        }

        public MySQLiteDBHelper(Context context) {
            super(context, SQL_DB_NAME, null, DATABASE_VERSION);
        }

        /**
         * Creates the data repository. This is called when the provider
         * attempts to open the repository and SQLite reports that it doesn't
         * exist.
         */
        @Override
        public void onCreate(SQLiteDatabase db) {
            // Creates the main table
            db.execSQL(SQL_CREATE_TABLE_STATEMENT);
        }

        @Override
        public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
            db.execSQL("DROP TABLE IF EXISTS " + SQL_MAIN_TABLE_NAME);
            onCreate(db);
        }
    }

    private MySQLiteDBHelper dbHelper;
    private UriMatcher sUriMatcher;

    /**
     * @see android.content.ContentProvider#onCreate()
     */
    @Override
    public boolean onCreate() {
        dbHelper = new MySQLiteDBHelper(getContext());

        sUriMatcher = new UriMatcher(UriMatcher.NO_MATCH);
        sUriMatcher.addURI(AUTHORITY, MySQLiteDBHelper.SQL_MAIN_TABLE_NAME, TRANSPORT);

        return true;
    }

    /**
     * @see android.content.ContentProvider#query(android.net.Uri,
     *      java.lang.String[], java.lang.String, java.lang.String[],
     *      java.lang.String)
     */
    @Override
    public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs,
            String sortOrder) {
        SQLiteQueryBuilder qb = new SQLiteQueryBuilder();

        switch (sUriMatcher.match(uri)) {
        case TRANSPORT:
            qb.setTables(MySQLiteDBHelper.SQL_MAIN_TABLE_NAME);
            break;

        default:
            throw new IllegalArgumentException("Unknown URI " + uri);
        }

        SQLiteDatabase db = dbHelper.getReadableDatabase();
        Cursor c = qb.query(db, projection, selection, selectionArgs, null, null, sortOrder);
        // in case there are changes while this cursor is processed.
        c.setNotificationUri(getContext().getContentResolver(), uri);
        return c;

    }

    /**
     * @see android.content.ContentProvider#getType(android.net.Uri)
     */
    @Override
    public String getType(Uri uri) {
        switch (sUriMatcher.match(uri)) {
        case TRANSPORT:
            return CONTENT_TYPE;
        default:
            throw new IllegalArgumentException("Unknown URI " + uri);
        }
    }

    /**
     * @see android.content.ContentProvider#insert(android.net.Uri,
     *      android.content.ContentValues)
     */
    @Override
    public Uri insert(Uri uri, ContentValues values) {
        if (sUriMatcher.match(uri) != TRANSPORT || values == null || values.size() == 0) {
            throw new IllegalArgumentException("Unknown URI " + uri);
        }

        SQLiteDatabase db = dbHelper.getWritableDatabase();
        long rowId = db.insert(MySQLiteDBHelper.SQL_MAIN_TABLE_NAME, null, values);

        if (rowId > 0) {
            Uri noteUri = ContentUris.withAppendedId(CONTENT_URI, rowId);

            // a new row was inserted ==> notify the observers
            getContext().getContentResolver().notifyChange(CONTENT_URI, null);

            return noteUri;
        }

        throw new SQLException("Failed to insert row into " + uri);
    }

    /**
     * @see android.content.ContentProvider#delete(android.net.Uri,
     *      java.lang.String, java.lang.String[])
     */
    @Override
    public int delete(Uri uri, String where, String[] whereArgs) {
        SQLiteDatabase db = dbHelper.getWritableDatabase();
        int count;

        switch (sUriMatcher.match(uri)) {
        case TRANSPORT:
            count = db.delete(MySQLiteDBHelper.SQL_MAIN_TABLE_NAME, where, whereArgs);
            break;
        default:
            throw new IllegalArgumentException("Unknown URI " + uri);
        }

        return count;
    }

    /**
     * @see android.content.ContentProvider#update(android.net.Uri,
     *      android.content.ContentValues, java.lang.String, java.lang.String[])
     */
    @Override
    public int update(Uri uri, ContentValues values, String where, String[] whereArgs) {
        SQLiteDatabase db = dbHelper.getWritableDatabase();
        int count;

        switch (sUriMatcher.match(uri)) {
        case TRANSPORT:
            count = db.update(MySQLiteDBHelper.SQL_MAIN_TABLE_NAME, values, where, whereArgs);
            break;
        default:
            throw new IllegalArgumentException("Unknown URI " + uri);
        }

        return count;
    }
}
